﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

using Elifart.Editor.GeneralControls;
using Elifart.Library;

namespace Elifart.Editor.CategoryTabs.AthletesControls
{
    public partial class AthletesControl : UserControl
    {
        #region Constructor

        public AthletesControl()
        {
            InitializeComponent();
        }

        #endregion

        #region Private Fields

        private Athlete _selectedAthlete;
        
        private bool _updatingAthlete;
        private bool _loadingAthlete;

        private IEnumerable<Athlete> _searchResultsEnumerable;
        private IEnumerator<Athlete> _searchResultsEnumerator;

        #endregion

        #region Private Methods

        private void LoadAthlete()
        {
            if (this._updatingAthlete) return;
            
            Athlete athlete = this.lbx_athletes.SelectedItem as Athlete;
            this._loadingAthlete = true;

            this.pnl_athleteInfo.Enabled = athlete != null;
            this.pnl_athleteAttributes.Enabled = athlete != null;
            this.btn_removeAthlete.Enabled = athlete != null;
            this.btn_athletePicture.Enabled = athlete != null;
            this.btn_next.Enabled = athlete != null;

            if (athlete == null)
                this.ResetAthlete();
            else
            {
                this.LoadAthleteInfo(athlete);
                this.LoadAthletePicture(athlete);
                this._selectedAthlete = athlete;
            }

            this._loadingAthlete = false;
        }

        private void LoadAthleteInfo(Athlete athlete)
        {
            this.pnl_athleteInfo.Enabled = true;
            this.txt_athleteName.Text = athlete.Name;
            this.txt_athleteNickname.Text = athlete.Nickname;
            this.dtp_birthDate.Text = athlete.BirthDate.ToShortDateString();
        }

        private void LoadAthletePicture(Athlete athlete)
        {
            this.pbx_athletePicture.Image = AthleteManager.GetManager().GetAthletePicture(athlete.PictureName);
            if (this.pbx_athletePicture.Image == null)
                this.pbx_athletePicture.Image = Properties.Resources.face_silhouette;
        }

        private void NewAthlete()
        {
            Athlete athlete = new Athlete();
            athlete.Name = "João Ninguém da Silva";
            athlete.Nickname = "João Ninguém";
            athlete.BirthDate = DateTime.Now;
            athlete.PictureName = string.Empty;

            if (AthleteManager.GetManager().Athletes.Contains(athlete)) return;
            
            AthleteManager.GetManager().Athletes.Add(athlete);
            int index = this.lbx_athletes.Items.Add(athlete);
            this.lbx_athletes.SelectedIndex = index;
        }

        private void RemoveAthlete()
        {
            Athlete athlete = this.lbx_athletes.SelectedItem as Athlete;
            if (athlete == null) return;            
            
            AthleteManager.GetManager().Athletes.Remove(athlete);
            int index = this.lbx_athletes.Items.IndexOf(athlete);

            this.lbx_athletes.Items.Remove(athlete);

            if (index != 0)
                this.lbx_athletes.SelectedIndex = (index - 1);
        }

        private void UpdateAthlete()
        {
            Athlete athlete = this.lbx_athletes.SelectedItem as Athlete;
            if (athlete == null) return;

            this._updatingAthlete = true;
            athlete.Nickname = this.txt_athleteNickname.Text;
            this.lbx_athletes.Items.Remove(athlete);
            int index = this.lbx_athletes.Items.Add(athlete);
            this.lbx_athletes.SelectedIndex = index;
            this._updatingAthlete = false;
        }

        private void ResetAthlete()
        {
            this.ResetAthleteInfoInterface();
            this.ResetAthletePicture();
        }

        private void ResetAthleteInfoInterface()
        {
            this.txt_athleteName.Text = string.Empty;
            this.txt_athleteNickname.Text = string.Empty;
            this.dtp_birthDate.ResetText();
        }

        private void ResetAthletePicture()
        {
            this.pbx_athletePicture.Image = Properties.Resources.face_silhouette;
        }

        private void SearchNextAthlete()
        {
            if (this._searchResultsEnumerator == null) return;
            if (!this._searchResultsEnumerator.MoveNext())
            {
                this._searchResultsEnumerator = this._searchResultsEnumerable.GetEnumerator();
                this._searchResultsEnumerator.MoveNext();
            }

            this.lbx_athletes.SelectedItem = this._searchResultsEnumerator.Current;
        }

        private void SearchAthlete(Athlete athlete, string searchPattern)
        {
            var lastsearchResults = from item in AthleteManager.GetManager().Athletes
                                    where (item as Athlete).Nickname.StartsWith(this.txt_athletesSearch.Text, StringComparison.InvariantCultureIgnoreCase)
                                    select item as Athlete;

            this._searchResultsEnumerable = lastsearchResults;
            this._searchResultsEnumerator = this._searchResultsEnumerable.GetEnumerator();
            this.SearchNextAthlete();
        }

        #endregion

        #region Public Methods

        public void LoadAthletes()
        {
            foreach (Athlete athlete in AthleteManager.GetManager().Athletes)
                this.lbx_athletes.Items.Add(athlete);

            if (this.lbx_athletes.Items.Count > 0)
                this.lbx_athletes.SelectedIndex = 0;
        }

        #endregion

        #region Signed Event Methods

        private void btn_newAthlete_Click(object sender, System.EventArgs e)
        {
            this.NewAthlete();
        }

        private void btn_next_Click(object sender, EventArgs e)
        {
            this.SearchNextAthlete();
        }

        private void btn_removeAthlete_Click(object sender, System.EventArgs e)
        {
            this.RemoveAthlete();
        }

        private void btn_athletePicture_Click(object sender, EventArgs e)
        {
            Athlete athlete = this.lbx_athletes.SelectedItem as Athlete;
            if (athlete == null) return;
            athlete.Name = this.txt_athleteName.Text;

            FileChooser chooser = new FileChooser(athlete.PictureName,AthleteManager.ATHLETES_PICTURES_DIRECTORY);
            chooser.StartPosition = FormStartPosition.CenterParent;

            DialogResult result = chooser.ShowDialog(this);
            if (result != DialogResult.OK) return;

            athlete.PictureName = chooser.SelectedImage;

            this.LoadAthlete();
        }

        private void dtp_birthDate_ValueChanged(object sender, EventArgs e)
        {
            if (this._loadingAthlete) return;
            Athlete athlete = this.lbx_athletes.SelectedItem as Athlete;
            if (athlete == null) return;
            athlete.BirthDate = this.dtp_birthDate.Value;
        }

        private void lbx_athletes_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this._updatingAthlete) return;
            this.LoadAthlete();
        }

        private void txt_athleteName_TextChanged(object sender, EventArgs e)
        {
            if (this._loadingAthlete) return;
            Athlete athlete = this.lbx_athletes.SelectedItem as Athlete;
            if (athlete == null) return;
            athlete.Name = this.txt_athleteName.Text;
        }

        private void txt_athleteNickname_TextChanged(object sender, EventArgs e)
        {
            if (this._loadingAthlete) return;
            this.UpdateAthlete();
        }

        private void txt_athletesSearch_TextChanged(object sender, EventArgs e)
        {
            this.SearchAthlete(null, this.txt_athletesSearch.Text);
        }

        #endregion
    }
}
